#pragma once
#include <iostream>
#include <filesystem>
#include "socket.hpp"

using func_t = function<string(string &)>; // 执行任务的方法

// Http底层是采用tcp协议

class delfile
{
    filesystem::path directory = "LogFile";

public:
    delfile()
    {
        try
        {
            if (filesystem::exists(directory) && filesystem::is_directory(directory))
            {
                for (const auto &entry : filesystem::recursive_directory_iterator(directory))
                {
                    if (filesystem::is_regular_file(entry.path()))
                    {
                        // 删除文件
                        filesystem::remove(entry.path());
                        std::cout << "已删除文件: " << entry.path() << std::endl;
                    }
                    else if (filesystem::is_directory(entry.path()))
                    {
                        // 删除目录
                        filesystem::remove_all(entry.path());
                        std::cout << "已删除目录: " << entry.path() << std::endl;
                    }
                }
            }
        }
        catch (const filesystem::filesystem_error &e)
        {
            std::cerr << "处理目录时出错: " << e.what() << std::endl;
        }
    }
};
class Tcp_server
{
public:
    Tcp_server(uint16_t port, func_t f)
        : _port(port), _sv(make_unique<tcp_socket>()), _func(f)
    {
        _sv->tcpserver_socket(port); // 创建套接字+绑定+监听
        unique_ptr<delfile> help = make_unique<delfile>();
    }

    // 服务端与客户端建立连接后，服务端的一个线程与客户端进行通信
    void thread_run(my_socket *socket)
    {
        cout << socket->Get_sockfd() << endl;
        cout << "------------------" << endl;
        while (true)
        {
            string http_request, onerecv;
            // 1.请求内容处理时要进行一次完整的报文提取

            int length = 0; // 记录请求内容长度
            while (socket->Recv(onerecv, 512))
            {
                http_request += onerecv;
                // 找Content-Length
                if (length == 0)
                {
                    size_t pos = http_request.find("Content-Length:");
                    if (pos != string::npos)
                    {
                        size_t pos1 = onerecv.find("\r\n", pos + 16);
                        if (pos1 != string::npos)
                        {
                            length = stoi(onerecv.substr(pos + 16, pos1 - pos));
                            cout << "----------------------------------Content-Length: " << length << endl;
                        }
                    }
                }

                size_t pos = http_request.find("\r\n\r\n");
                if (pos != string::npos)
                {
                    pos += 4;
                    // 读取请求内容
                    while (true)
                    {
                        if (pos + length <= http_request.size())
                        {
                            string ret = http_request.substr(pos + length);
                            http_request.erase(pos + length);

                            // cout << http_request << endl;
                            // 2.回调http提供的处理请求内容的方法，并返回响应内容
                            string Http_response = _func(http_request);

                            // 3.将执行后的数据返回发送给客户端（浏览器）
                            socket->Send(Http_response);

                            http_request = ret;

                            break;
                        }
                        else
                        {
                            length -= http_request.size() - pos;
                            socket->Recv(onerecv, 128);
                            http_request += onerecv;
                        }
                    }
                }
            }
        }
    }

    void loop()
    {
        while (1)
        {
            string client_ip;
            uint16_t client_port;
            my_socket *socket = _sv->Accept(client_ip, client_port); // 接收套接字
            if (socket == nullptr)
            {
                break;
            }
            cout << "获取新连接,ip= " << client_ip << " port= " << client_port << endl;

            // 创建线程执行任务
            thread t(&Tcp_server::thread_run, this, socket);
            t.detach(); // 线程分离
        }
    }

private:
    unique_ptr<my_socket> _sv;
    uint16_t _port;
    func_t _func;
};
